/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.opengoofy.congomall.biz.basicdata.infrastructure.repository;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import lombok.RequiredArgsConstructor;
import org.opengoofy.congomall.biz.basicdata.domain.aggregate.RegionInfo;
import org.opengoofy.congomall.biz.basicdata.domain.repository.RegionInfoRepository;
import org.opengoofy.congomall.biz.basicdata.infrastructure.dao.mapper.RegionInfoMapper;
import org.opengoofy.congomall.biz.basicdata.infrastructure.dao.entity.RegionInfoDO;
import org.opengoofy.congomall.springboot.starter.common.toolkit.BeanUtil;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.function.Function;

/**
 * 行政区划仓储层实现
 *
 * @author chen.ma
 * @github <a href="https://github.com/opengoofy" />
 * @公众号 马丁玩编程，关注回复：资料，领取后端技术专家成长手册
 */
@Repository
@RequiredArgsConstructor
public class RegionInfoRepositoryImpl implements RegionInfoRepository {
    
    private final RegionInfoMapper regionInfoMapper;
    
    @Override
    public List<RegionInfo> listAllRegionInfo() {
        return BeanUtil.convert(getRegionInfoList(null, null), RegionInfo.class);
    }
    
    @Override
    public List<RegionInfo> listRegionInfoByLevel(Integer level) {
        return BeanUtil.convert(getRegionInfoList(RegionInfoDO::getLevel, level), RegionInfo.class);
    }
    
    @Override
    public List<RegionInfo> listRegionInfoByCode(String code) {
        return BeanUtil.convert(getRegionInfoList(RegionInfoDO::getCode, code), RegionInfo.class);
    }
    
    @Override
    public List<RegionInfo> listRegionInfoByParent(String parent) {
        return BeanUtil.convert(getRegionInfoList(RegionInfoDO::getParent, parent), RegionInfo.class);
    }
    
    /**
     * 获取区域信息列表
     *
     * @param field 字段      e.g RegionInfoDO::getParent
     * @param value 字段值    e.g parent
     * @return {@code List<RegionInfoDO>}
     */
    private List<RegionInfoDO> getRegionInfoList(Function<RegionInfoDO, Object> field, Object value) {
        LambdaQueryWrapper<RegionInfoDO> queryWrapper = Wrappers.lambdaQuery(RegionInfoDO.class)
                .select(
                        RegionInfoDO::getId,
                        RegionInfoDO::getCode,
                        RegionInfoDO::getName,
                        RegionInfoDO::getParent,
                        RegionInfoDO::getLevel,
                        RegionInfoDO::getSort);
        addEq(queryWrapper, field, value);
        return regionInfoMapper.selectList(queryWrapper);
    }
    
    /**
     * 查询器增加条件
     *
     * @param queryWrapper 查询wrapper
     * @param field        字段
     * @param value        值
     */
    private <T> void addEq(LambdaQueryWrapper<T> queryWrapper, Function<T, Object> field, Object value) {
        if (value != null) {
            queryWrapper.eq((SFunction<T, ?>) field, value);
        }
    }
    
}
